package com.sitech.ibnms.util;

/**
 *
 * @author liujhc <liujhc@si-tech.com.cn>
 */
public class IPv4Util {

    /**
     * 验证ip字符串是否合法
     *
     * @param ip 如 192.168.1.12
     * @return
     */
    public static boolean isValidIp(String ip) {
        return ip != null && ip.matches("\\b(([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\.){3}([01]?\\d?\\d|2[0-4]\\d|25[0-5])\\b");
    }

    /**
     * 将ip字符串解析成数值
     *
     * @param ip 如 192.168.1.12
     * @return
     */
    public static long parseIpToValue(String ip) {
        if (isValidIp(ip)) {
            long value = 0;
            String[] arr = ip.split("\\.");
            for (int i = 0; i < 4; i++) {
                value += Long.parseLong(arr[i]) << (8 * (3 - i));
            }
            return value;
        }
        return -1;
    }

    /**
     * 子网掩码所代表子网的ip容量
     *
     * @param netmask 如： 255.255.0.0
     * @return 当提供的子网掩码无效时返回-1
     */
    public static long getSubnetCapacity(String netmask) {
        long value = IPv4Util.parseIpToValue(netmask);
        return Long.toBinaryString(value).matches("^1+0+$") ? value ^ ((1L << 32) - 1) : -1;
    }

    /**
     * <pre>子网掩码所代表子网的ip容量
     *  8 --> 255.0.0.0
     * 16 --> 255.255.0.0
     * 24 --> 255.255.255.0</pre>
     * @param netmask 如 24
     * @return 当提供的子网掩码无效时返回-1
     */
    public static long getSubnetCapacity(int netmask) {
        return netmask > 0 && netmask < 32 ? (1L << (32 - netmask)) - 1 : -1;
    }

    /**
     * 将ip由数值转换成192.168.1.1样式的文本
     *
     * @param ipvalue
     * @return
     */
    public static String toIpText(long ipvalue) {
        if (ipvalue < 1L << 32) {
            int[] ai = new int[4];
            for (int i = 0; i < 4 && ipvalue != 0; i++) {
                long tmp = ipvalue;
                ipvalue >>= 8;
                ai[i] = (int) (tmp - (ipvalue << 8));
            }
            return ai[3] + "." + ai[2] + "." + ai[1] + "." + ai[0];
        }
        return "INVALID IP";
    }

    public static void main(String[] args) {
        System.out.println("getSubnetCapacity(24) = " + getSubnetCapacity(24));
        System.out.println("getSubnetCapacity(\"255.255.255.0\") = " + getSubnetCapacity("255.255.255.0"));
    }
}
